
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct tag_Lex Lex;
struct tag_Lex{
    Lex * parent;
    Lex * child;
    Lex * next;
    Lex * last;
    char stat[1024];
};

void print_level(int level){
    while(level > 0){
        printf("    ");
        level --;
    }
}

void print_lex(Lex * lex, int level){
    Lex * cur = lex;
    Lex * child;
    while(cur->child){
        child = cur->child;
        print_level(level);
        printf("%s\n", child->stat);
        while(child->next){
            child = child->next;
            print_level(level);
            printf("%s\n", child->stat);
            print_lex(child, level + 1);
        }
        cur = cur->child;
    }
}

int parse_statement(char * script, size_t len){
    Lex *lex = malloc(sizeof(Lex));
    memset(lex, 0, sizeof(Lex));
    char stat[1024];
    size_t stat_len = 0;
    size_t i = 0;
    Lex * cur = NULL;
    Lex * n = NULL;
    while(i < len){
        char c = script[i];
        i++;
        switch(c){
            case ' ':
            case '\r':
            case '\n':
            case '\t':
                if(stat_len > 0){
                    stat[stat_len] = 0;
                    printf("%d %s\n", i, stat);
                    n = malloc(sizeof(Lex));
                    memset(n, 0, sizeof(Lex));
                    n->parent = lex;
                    memcpy(n->stat, stat, stat_len);
                    if(!cur){
                        n->parent = lex;
                        lex->child = n;
                    }else{
                        cur->next = n;
                        n->last = cur;
                    }
                    cur=n;
                    stat_len = 0;
                }
                break;
            case '(':
            case '{':
                if(stat_len > 0){
                    stat[stat_len] = 0;
                    printf("%d %s\n", i, stat);
                    n = malloc(sizeof(Lex));
                    memset(n, 0, sizeof(Lex));
                    n->parent = lex;
                    memcpy(n->stat, stat, stat_len);
                    if(!cur){
                        n->parent = lex;
                        lex->child = n;
                    }else{
                        cur->child = n;
                        n->parent = cur;
                    }
                    stat_len = 0;
                    cur=n;
                }
                printf("%d %c\n", i, c);
                break;
            case ')':
            case '}':
                if(stat_len > 0){
                    stat[stat_len] = 0;
                    printf("%d %s\n", i, stat);
                    n = malloc(sizeof(Lex));
                    memset(n, 0, sizeof(Lex));
                    n->parent = lex;
                    memcpy(n->stat, stat, stat_len);
                    if(!cur){
                        n->parent = lex;
                        lex->child = n;
                    }else{
                        cur->parent->next = n;
                        n->last = cur->parent;
                    }
                    stat_len = 0;
                    cur=n;
                }
                printf("%d %c\n", i, c);
                break;
            default:
                stat[stat_len] = c;
                stat_len ++;
                break;
        }

    }
    printf("-------\n");
    print_lex(lex, 0);
}

int main(){
    FILE * f = fopen("t.dua", "rb");
    char script[2048];
    fread(script, 2048,1, f);
    size_t len = strlen(script);

    parse_statement(script, len);

    return 0;
}
